#include "view.h"

#include <iostream>
#include <sstream>

#include "character.h"
#include "coordinates.h"
#include "maps.h"

using namespace fortress;

view::view(): width(80), height(24), maxDisplayItems(20), colors(width, std::vector<TCODColor>(height, TCODColor(120,120,120))), hp(0), maxHp(0)
{
	currentMap=0;
	clearList = new std::list<COORD*>;
}

view::~view()
{

	for(std::list<COORD*>::iterator it=clearList->begin(); it!=clearList->end(); it++)
	{
		delete *it;
	 }
	delete clearList;

}

void view::getMapData()
{

}

void view::drawGlyph(int x, int y, char glyph, TCODColor color)
{
	if (currentMap->getExplored(x,y))
		TCODConsole::root->putCharEx(x,y+1,static_cast<int>(glyph),color,TCODColor(0,0,0));
	else
		TCODConsole::root->putCharEx(x,y+1,' ',color,TCODColor(0,0,0));
}

void view::drawMap()
{
	for (int i=0; i<width; i++)
	{
		for (int j=0; j<height; j++)
		{
			drawGlyph(i,j,currentMap->getTile(i,j),colors[i][j]);
		}
	}
}

void view::printMessage(std::string const & displayString)
{
	clearMessage();
	TCODConsole::root->printLeft(0, 0, TCOD_BKGND_NONE, displayString.c_str());
	TCODConsole::root->flush();
}

void view::clearMessage()
{
	TCODConsole::root->rect(0, 0, width, 1, 1, TCOD_BKGND_NONE);
}

void view::printError(std::string const & displayString)
{
	std::cerr << "Error: " << displayString << "\n";
}

void view::printDebug(std::string const & displayString)
{
	std::cerr << displayString;
}

void view::draw()
{
//	clearMessage();	// Clears the message output
	std::list<COORD*> * drawList = currentMap->getDrawList(0);
	std::list<COORD*>::iterator it;
	COORD * temp;
	drawMap();
 	for(it=clearList->begin(); it!=clearList->end(); it++)
	{
		temp = *it;
		drawGlyph(temp->x,temp->y,currentMap->getTile(temp->x,temp->y),colors[temp->x][temp->y]);
		delete *it;
		
	}
	for(it=drawList->begin(); it!=drawList->end(); it++)
	{
		temp = *it;
		drawGlyph(temp->x,temp->y,temp->glyph,temp->color);
	}
	
	// Remember the spots we drew on this turn.  We'll have to redo this once we get more lazy about drawing
	
	std::ostringstream health;
	health << "HP: " << hp << "/" << maxHp << "  ";
	//health = string(hp); ostream
	TCODConsole::root->printLeft(2, 23, TCOD_BKGND_NONE,health.str().c_str());
	clearList->clear();
	clearList->splice(clearList->begin(), *drawList, drawList->begin(), drawList->end());
	delete drawList;
	TCODConsole::root->flush();
}

void view::setMap(map * newMap)
{
	currentMap=newMap;
	drawMap();
//	currentMap->getMapData(display);
}

std::vector<int> view::drawMenu(std::vector<std::string*> data, std::string message, bool readOnly)
{
	unsigned i=0;
	std::vector<int> selected(data.size(), 0);
	unsigned int j=data.size();
	if (j==0)
	{
		TCODConsole::root->clear();
		TCODConsole::root->printLeft(2,0,TCOD_BKGND_NONE,message.c_str());
		TCODConsole::root->printLeft(2,2,TCOD_BKGND_NONE,"There is nothing to see here.");
		TCODConsole::root->flush();
		TCODConsole::waitForKeypress(true);
	}
	while (j!=0)
	{
		unsigned int i;	// I'm going to use i later to determine how many items were drawn onto the screen
		TCODConsole::root->clear();
		TCODConsole::root->printLeft(2,0,TCOD_BKGND_NONE,message.c_str());
		for(i=0; i<j && i<maxDisplayItems; i++)
		{
			char prefix;
			if(selected[i+data.size()-j]==0)
				prefix='-';
			else
				prefix='+';
			std::string print;
			print +=(i+97);
			print += ' ';
			print += prefix;
			print += ' ';
			print += data[i+data.size()-j]->c_str();
			TCODConsole::root->printLeft(2,i+2,TCOD_BKGND_NONE,print.c_str());
		}
		std::ostringstream pageStream;
		pageStream << "Page " << ((data.size()-j)/maxDisplayItems)+1 << '/' << (data.size()-1)/maxDisplayItems+1;
		TCODConsole::root->printLeft(30,i+4,TCOD_BKGND_NONE,pageStream.str().c_str());
		TCODConsole::root->flush();
		TCOD_key_t key;
		key.vk=TCODK_NONE;
		while (key.vk == TCODK_SHIFT || key.vk == TCODK_NONE)
		{
			key=TCODConsole::waitForKeypress(true);
		}
		if (key.vk==TCODK_CHAR && !readOnly)
		{
			unsigned int toggle = key.c-97;
			if (toggle>= 0 && toggle <i)
			{
				selected[toggle+data.size()-j] = !selected[toggle+data.size()-j];
			}
		} else if (key.vk==TCODK_SPACE || key.vk==TCODK_ENTER)
		{
			j-=i;	// go to the next screen of items
		} else if (key.vk==TCODK_ESCAPE)
		{
			drawMap();
			std::vector<int> blank;
			return blank; // cancel
		}
	}
	drawMap();
	return selected;
}

void view::drawHealth(int newHp, int newMaxHp)
{
	hp=newHp;
	maxHp=newMaxHp;
}